package mysql8学习.高级.第10章_索引优化与查询优化;

/**
 * 2.索引失效案例
 * MySQL中提高性能的一个最有效的方式是对数据表设计合理的索引。
 * 索引提供了高效访问数据的方法,并且加快查询的速度，因此索引对查询的速度有着至关重要的影响。
 * ●使用索引可以快速地定位表中的某条记录，从而提高数据库查询的速度，提高数据库的性能。
 * ●如果查询时没有使用索引，查询语句就会扫描表中的所有记录。在数据量大的情况下，这样查询的速度会很慢。
 *  大多数情况下都(默认)采用B+树来构建索引。只是空间列类型的索引使用R-树,并且MEMORY表还支持hash索引。
 *
 * 其实,用不用索引，最终都是优化器说了算。优化器是基于什么的优化器?
 * 基于cost开销(CostBaseOptimizer),它不是基于规则(Rule-BasedOptimizer),也不是基于语义。
 * 怎么样开销小就怎么来。
 * 另外，SQL语句是否使用索引，跟数据库版本、数据量、数据选择度都有关系。
 *
 *
 */
public class B0_索引失效案例 {
}
/**
 * 2.1 全值匹配我最爱
 * 没有索引，全表扫描
 */
/**
 * 2.2 最佳左前缀法则
 * 在MySQL建立联合索引时会遵守最佳左前缀匹配原则，即最左优先，
 * 在检索数据时从联合索引的最左边开始匹配。
 *
 * 结论: MySQL可以为多个字段创建索引，一个索引可以包括16个字段。
 * 对于多列索引,过滤条件要使用索引必须按照索引建立时的顺序,依次满足，
 * 一旦跳过某个字段，索引后面的字段都无法被使用。
 * 如果查询条件中没有用这些字段中第1个字段时，多列(或联合)索引不会被使用。
 */
/**
 * 2.3 主键插入顺序   AUTO_INCREMENT  自动递增
 * 对于一个使用InnoDB存储引擎的表来说，在我们没有显式的创建索引时,
 * 表中的数据实际上都是存储在聚簇索引的叶子节点的。
 * 而记录又是存储在数据页中的,数据页和记录又是按照记录主键值从小到大的顺序进行排序,
 * 所以如果我们插入的记录的主键值是依次增大的话,那我们每插满一个数据页就换到下一个数据页继续插，
 * 而如果我们插入的主键值忽大忽小的话,就比较麻烦了，假设某个数据页存储的记录已经满了，
 * 它存储的主键值在1~100之间:
 *
 * 可这个数据页已经满了，再插进来咋办呢?我们需要把当前页面分裂成两个页面，
 * 把本页中的一些记录移动到新创建的这个页中。页面分裂和记录移位意味着什么?
 * 意味着:性能损耗!所以如果我们想尽量避免这样无谓的性 能损耗，
 * 最好让插入的记录的主键值依次递增，这样就不会发生这样的性能损耗了。
 * 所以我们建议:让主键具有AUTO_INCREMENT，让存储引擎自己为表生成主键，而不是我们手动插入，
 *
 *
 */
/**
 * 2.4 计算、函数、类型转换(自动或手动)导致索引失效
 *
 * 索引列  最好不要用函数  否则容易索引失效
 * 计算、函数、类型转换(自动或手动)导致索引失效
 *
 */
/**
 * 2.5 类型转换导致索引失效
 */
/**
 * 2.6 范围条件右边的列索引失效
 *      创建 联合索引 时
 *      如 CREATE INDEX 索引名 ON 表名(字段一,字段二,字段三);
 *      where 字段一 = 值 and 字段二 > 值 and 字段三 = 值
 *      这样的话  字段三就用不到索引了  ，范围条件右边的列索引失效 可以改成
 *     CREATE INDEX 索引名 ON 表名(字段一,字段三,字段二);  就行了
 *
 *  应用开发中范围查询，例如:金额查询，日期查询往往都是范围查询。应将查询条件放置where语句最后。
 * (创建的联合索引中，务必把范围涉及到的字段写在最后)
/**
 * 2.7 不等于(!=或者<>)索引失效   索引可能失效  如果select * 的话  需要回表，不用索引
 *                                    如果select 索隐带的字段 的话  不需要回表，用索引
 */
/**
 * 2.8 is null可以使用索引，is not null无法使用索引
 *    结论:最好在设计数据表的时候就将字段设置为NOT NULL 约束，
 *    比如你可以将INT类型的字段，默认值设置为0。将字符类型的默认值设置为空字符串(“”)。
 *    拓展:同理，在查询中使用not like也无法使用索引，导致全表扫描。
 */
/**
 * 2.9 like以通配符%开头索引失效
 */
/**
 * 2.10 OR前后存在非索引的列，索引失效     前后都有索引会用到索引
 */
/**
 * 2.11 数据库和表的字符集统一使用utf8mb4
 * 统一使用utf8mb4(5.5.3版本以上支持)兼容性更好，统-字符集可以避免由于字符集转换产F生的乱码。
 * 不同的字符集进行比较前需要进行转换会造成索引失效。
 */
/**
 * 一般性建议:
 * ●对于单列索引，尽量选择针对当前query过滤性更好的索引
 * ●在选择组合索引的时候，当前query中过滤性最好的字段在索引字段顺序中，位置越靠前越好。
 * ●在选择组合索引的时候，尽量选择能够包含当前query中的where子句中更多字段的索引。
 * ●在选择组合索引的时候，如果某个字段可能出现范围查询时，尽量把这个字段放在索引次序的最后面。
 * 总之，书写SQL语句时，尽量避免造成索引失效的情况。
 *
 */